package com.lifeverse.entity;

import com.lifeverse.entity.enums.HealthStatus;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 健康检查实体
 */
@Entity
@Table(name = "health_checks")
@Data
@EqualsAndHashCode(callSuper = true)
public class HealthCheck extends BaseEntity {

    /**
     * 服务名称
     */
    @Column(nullable = false, length = 100)
    private String serviceName;

    /**
     * 健康检查名称
     */
    @Column(nullable = false, length = 100)
    private String checkName;

    /**
     * 健康状态
     */
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private HealthStatus status;

    /**
     * 健康分数 (0.0 - 1.0)
     */
    @Column(nullable = false)
    private Double healthScore;

    /**
     * 检查时间
     */
    @Column(nullable = false)
    private LocalDateTime checkTime;

    /**
     * 响应时间（毫秒）
     */
    private Long responseTimeMs;

    /**
     * 检查详情
     */
    @Column(columnDefinition = "TEXT")
    private String details;

    /**
     * 错误信息
     */
    @Column(columnDefinition = "TEXT")
    private String errorMessage;

    /**
     * 检查结果数据（JSON格式）
     */
    @ElementCollection
    @CollectionTable(name = "health_check_data", joinColumns = @JoinColumn(name = "health_check_id"))
    @MapKeyColumn(name = "data_key")
    @Column(name = "data_value", columnDefinition = "TEXT")
    private Map<String, String> checkData;

    /**
     * 检查URL或端点
     */
    @Column(length = 500)
    private String endpoint;

    /**
     * 检查间隔（秒）
     */
    private Integer intervalSeconds;

    /**
     * 超时时间（秒）
     */
    private Integer timeoutSeconds;

    /**
     * 重试次数
     */
    private Integer retryCount;

    /**
     * 是否启用
     */
    @Column(nullable = false)
    private Boolean enabled = true;

    /**
     * 最后成功检查时间
     */
    private LocalDateTime lastSuccessTime;

    /**
     * 最后失败检查时间
     */
    private LocalDateTime lastFailureTime;

    /**
     * 连续失败次数
     */
    @Column(nullable = false)
    private Integer consecutiveFailures = 0;

    /**
     * 连续成功次数
     */
    @Column(nullable = false)
    private Integer consecutiveSuccesses = 0;

    /**
     * 判断是否健康
     */
    public boolean isHealthy() {
        return status != null && status.isNormal();
    }

    /**
     * 判断是否需要立即关注
     */
    public boolean requiresAttention() {
        return status != null && status.requiresImmediateAttention();
    }

    /**
     * 更新检查结果
     */
    public void updateResult(HealthStatus newStatus, Double score, Long responseTime, String details) {
        this.status = newStatus;
        this.healthScore = score;
        this.responseTimeMs = responseTime;
        this.details = details;
        this.checkTime = LocalDateTime.now();

        if (newStatus.isNormal()) {
            this.consecutiveSuccesses++;
            this.consecutiveFailures = 0;
            this.lastSuccessTime = LocalDateTime.now();
            this.errorMessage = null;
        } else {
            this.consecutiveFailures++;
            this.consecutiveSuccesses = 0;
            this.lastFailureTime = LocalDateTime.now();
        }
    }

    /**
     * 设置错误信息
     */
    public void setError(String errorMessage) {
        this.errorMessage = errorMessage;
        this.status = HealthStatus.DOWN;
        this.healthScore = 0.0;
        this.consecutiveFailures++;
        this.consecutiveSuccesses = 0;
        this.lastFailureTime = LocalDateTime.now();
        this.checkTime = LocalDateTime.now();
    }
}